#! /usr/bin/env python
#coding=utf-8
import math3d,math


LEFT_SIDE = 0x01
RIGHT_SIDE = 0x02
NONE_SIDE = 0x03


def angle(o, s, e):
	cosfi = 0
	fi = 0
	norm = 0
	dsx = s[0] - o[0]
	dsy = s[1] - o[1]
	dex = e[0] - o[0]
	dey = e[1] - o[1]

	cosfi = dsx * dex + dsy * dey
	norm = (dsx * dsx + dsy * dsy) * (dex * dex + dey * dey)
	cosfi /= math.sqrt(norm)

	fi = math.acos(cosfi)
	if (180 * fi / math.pi < 180):
		return 180 * fi / math.pi
	else:
		return 360 - 180 * fi / math.pi

def angle360(o, s, e):
	if postionsame(o, s) or postionsame(o, e) or postionsame(s, e):
		return

	rotate = angle(o, s, e)
	dir = math3d.vector2(e[0], e[1]) - math3d.vector2(s[0], s[1])
	dir.normalize(1)
	x = 0
	y = 0
	if dir.x < 0:
		rotate = 360 - rotate
	return rotate * math.pi/180

# 两点相等
def postionsame(p0,p1):
	if p0[0] == p1[0] and p0[1] == p1[1]:
		return True
	return False


#单位化向量
def normalize(v=[]):
    if len(v) == 2:
        length = lambda v: (v[0]*v[0] + v[1]*v[1] ) ** 0.5
        return ( v[0] / length(v), v[1] / length(v))
    else:
        return 0

# 计算三点的夹角
def vector3angle(A, B, C):
	x1 = A[0]-B[0]
	y1 = A[1]-B[1]
	x2 = C[0]-B[0]
	y2 = C[1]-B[1]
	x = x1*x2+y1*y2
	y = x1*y2-x2*y1
	#if(   x> 0   )
	#      //角度 <90
	#else
	#      //角度> =90
	angle = math.acos(x/(x*x+y*y))
	#print "vector3angle",angle
	angle = math.acos(x/math.sqrt(x*x+y*y))
	return angle

#两向量的夹角(渣 无用)
def vector2angle(da, db):
	X1 = da[0]
	X2 = db[0]
	Y1 = da[1]
	Y2 = db[1]
	angle = (X1*X2+Y1*Y2)/(math.sqrt(X1^2+X2^2)(X2^2+Y2^2))
	return angle


# 逆时针 旋转向量
def RotateVectorN(x,y,d):
	p = ( x * math.cos(d) - y * math.sin(d) , x * math.sin(d) + y * math.cos(d) )
	return p


# 获得角对角d距离的点(渣 无用)
def anglepoint(p1, p2, p3, d):
	da = ((p2[0] - p1[0]), (p2[1] - p1[1]))
	#单位化
	v = [da[0], da[1]]
	da = normalize(v)
	# 夹角
	angle = vector3angle(p1, p2, p3)
	ds = da
	# 旋转夹角/2,得到中间向量
	dirz = RotateVectorN(ds[0], ds[1], angle/2)
	# p1的反向量顶点
	fp1 = (p2[0] + dirz[0] * d, p2[1] + dirz[1] * d)

	return fp1

# 计算线段长度
def linelength(p0, p1):
	x = math.fabs(p0[0]-p1[0])
	y = math.fabs(p0[1]-p1[1])
	length = math.sqrt(x*x + y*y)

	return length

# 计算三角形的重心(中心点)
def traingCenter(p0, p1, p2):
	x1 = p0[0]
	x2 = p1[0]
	x3 = p2[0]
	y1 = p0[1]
	y2 = p1[1]
	y3 = p2[1]

	pos = ((x1+x2+x3)/3,(y1+y2+y3)/3)
	return pos

# 判断相交
def isOnSameSide(x0, y0, x1, y1, x2, y2, x3, y3):
	a = y0 - y1
	b = x1 - x0
	c = x0 * y1 - x1 * y0

	if (a * x2 + b * y2 + c) * (a * x3 + b * y3 + c) > 0:
		return True
	return False

#p是要检测的点,v0,v1,v2是三角形的三个顶点。
# 计算点是否在三角形内
def isPointInside2(p, v0, v1, v2):
	if isOnSameSide(p[0] ,p[1] ,v0[0] ,v0[1] ,v1[0] ,v1[1] ,v2[0] ,v2[1]) or \
		isOnSameSide(p[0] ,p[1] ,v1[0] ,v1[1] ,v2[0] ,v2[1] ,v0[0] ,v0[1]) or \
			isOnSameSide(p[0] ,p[1] ,v2[0] ,v2[1] ,v0[0] ,v0[1] ,v1[0] ,v1[1]):
		return False
	return True


#线段求交点
def linenode(P1,P2,Q1,Q2):
	P1_X   =   P1[0]
	P2_X   =   P2[0]
	Q1_X   =   Q1[0]
	Q2_X   =   Q2[0]

	P1_Y   =   P1[1]
	P2_Y   =   P2[1]
	Q1_Y   =   Q1[1]
	Q2_Y   =   Q2[1]

	tmp11 = (Q1_X - P1_X) * (Q1_Y - Q2_Y) - (Q1_Y - P1_Y) * (Q1_X - Q2_X)
	tmp12 = (P2_X - P1_X) * (Q1_Y - Q2_Y) - (P2_Y - P1_Y) * (Q1_X - Q2_X)
	tmp13 = (P2_X - P1_X) * (Q1_Y - P1_Y) - (P2_Y - P1_Y) * (Q1_X - P1_X)
	tmp14 = (P2_X - P1_X) * (Q1_Y - Q2_Y) - (P2_Y - P1_Y) * (Q1_X - Q2_X)
	u = tmp11/tmp12
	v = tmp13/tmp14

	node = None
	#若参数值同时满足0≤u≤1，0≤v≤1,则两线段有交点
	if (0 <= u and u <= 1 and 0 <= v and v <= 1):
		x = P1_X + (P2_X - P1_X) * u
		y = P1_Y + (P2_Y - P1_Y) * u
		node = (x,y)

	return node

# 顺时针 旋转向量
def RotateVector(x,y,d):
	p = ( x * math.cos(-d) - y * math.sin(-d) , x * math.sin(-d) + y * math.cos(-d) )
	return p

# 获得一点与边的直角距离
def traingMiniWidth(p1,p2,p3):
	x = p1[0] - p2[0]
	y = p1[1] - p2[1]
	d = 90
	# 顺时针
	p = RotateVector(x, y, d)

	pe = ( p3[0] + p[0] * 1000, p3[1] + p[1] * 1000)
	pon = linenode(p1,p2,p3,pe)
	#print "xiangjiao:",pon
	length = 0
	if pon:
		length = linelength(pon, p3)

	return length

# 两点p1(x1,y1),p2(x2,y2),判断点p(x,y)在线的左边还是右边
def LeftOfLine(p, p1, p2):
	x1 = p1[0]
	x2 = p2[0]
	y1 = p1[1]
	y2 = p2[1]
	x = p[0]
	y = p[1]
    #tmpx = (p1[0] - p2[0]) / (p1[1] - p2[1]) * (p[1] - p2[1]) + p2[0];
	Tmp = (y1 - y2) * x + (x2 - x1) * y + x1 * y2 - x2 * y1

	if Tmp > 0:
		return LEFT_SIDE
	elif Tmp < 0:
		return RIGHT_SIDE
	else:
		return NONE_SIDE

    #if (tmpx > p[0]):#当tmpx>p.x的时候，说明点在线的左边，小于在右边，等于则在线上。
    #    return True
	#return False
#另外一种方法：
#Tmp = (y1 – y2) * x + (x2 – x1) * y + x1 * y2 – x2 * y1
#Tmp > 0 在左侧
#Tmp = 0 在线上
#Tmp < 0 在右侧
